﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MiniCPU.Events;

namespace MiniCPU.Entities
{
    /// <summary>
    /// Control Port class.
    /// </summary>
    public class ControlPort : DataPropagator
    {
        #region Variables
        /// <summary>
        /// List of sources connected to this port.
        /// </summary>
        private List<LimitedData> sources;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="ControlPort"/> class.
        /// </summary>
        /// <param name="name">The name of the control port.</param>
        public ControlPort(string name)
            : base(name, false)
        {
            this.sources = new List<LimitedData>();
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the value of this <see cref="ControlPort"/>.
        /// </summary>
        /// <value><c>true</c> if value is true; otherwise, <c>false</c>.</value>
        public bool Value
        {
            get
            {
                return this.BooleanValue;
            }

            set
            {
                this.BooleanValue = value;
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Adds a source.
        /// </summary>
        /// <param name="limitedData">The data holder.</param>
        public void AddSource(LimitedData limitedData)
        {
            this.sources.Add(limitedData);
            limitedData.DataChanged += new MiniCPU.Events.DataChangedEventHandler(this.ControlSignal_DataChanged);
        }

        /// <summary>
        /// Handles the DataChanged event of the ControlSignal control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="MiniCPU.Events.DataChangedEventArgs"/> instance containing the event data.</param>
        private void ControlSignal_DataChanged(object sender, MiniCPU.Events.DataChangedEventArgs e)
        {
            this.BooleanValue = this.sources.Select(x => x.BooleanValue).Aggregate((oring, holder) => oring |= holder);
        }
        #endregion
    }
}
